#include <stdio.h> 
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <stdlib.h>

#define NUM 1024 

struct MyFILE_
{
  int fd ;
  char buffer[1024] ;  // 文件缓冲区
  int end ;  // 文件缓冲区结尾
};

typedef struct MyFILE_ MyFILE ;



//利用open封装fopen,理解缓冲区在哪里
MyFILE* fopen_(const char* pathname , const char* mode)
{
  assert(pathname);
  assert(mode);

  MyFILE* fp = NULL;

  if(strcmp(mode, "r") == 0)
  {
  }
  else if(strcmp(mode,"r+")==0)
  {
  }
  else if(strcmp(mode,"w") == 0)
  {
      int fd = open(pathname, O_WRONLY | O_CREAT | O_TRUNC , 0666 ); //O_TRUNC：如果文件存在且以写方式打开，则将文件截断为空文件。
      if(fd >= 0)
      {
        fp = (MyFILE*)malloc(sizeof(MyFILE));
        memset(fp,0,sizeof(MyFILE));
        fp->fd = fd ;
      }
  } 
  else if(strcmp(mode,"w+")==0)
  {

  }
  else if(strcmp(mode,"a")==0)
  {

  }
  else if(strcmp(mode,"a+")==0)
  {

  }

  return fp;
}


void fputs_(const char  *message , MyFILE* fp)
{
  assert(message);
  assert(fp);

  strcpy(fp->buffer + fp->end , message); //因为fputs是续写
  fp->end += strlen(message);
  
  //printf("%s\n",fp->buffer);
  
  if(fp->fd == 0)
  {
    //标准输入
  }
  else if (fp->fd == 1)
  {
    //标准输出
    if(fp->buffer[fp->end-1] == '\n')
    {
      write(fp->fd ,fp->buffer,fp->end);
      fp->end = 0 ;
    }
  }
  if(fp->fd == 2)
  {
    //标准错误 
  }
  else
  {
    //其他文件 
  }
}

void fflush_(MyFILE* fp)
{
  assert(fp);

  if(fp->end != 0) //fp->end == 代表缓冲区无内容 
  {
    write(fp->fd , fp->buffer , fp->end);
    syncfs(fp->fd); //syncfs 函数用于将文件系统中的数据和元数据刷新到磁盘上
    fp->end = 0 ; 
  }
}


void fclose_(MyFILE* fp)
{
  assert(fp);
  fflush_(fp);
  close(fp->fd);
  free(fp);
}

int main()
{
  MyFILE* fp = fopen_("./log.txt","w");
  if(fp == NULL)
  {
    printf("open file error");
    return 1 ; 
  }

  fputs_("1: hello",fp);

  fork();

  fclose_(fp);
  return 0 ; 
}


//1.明白缓冲区在哪里
//2.知道C语言库是如何封装系统接口的
//3.知道fd是什么。











